/*-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License.You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
	
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.
	
The Original Code is Fever RS ( ActionScript 3 ) Framework code.
	
The Initial Developer of the Original Code is Romain Ecarnot.
Portions created by Initial Developer are Copyright (C) 2006
the Initial Developer. All Rights Reserved.
	
Contributor(s):
	
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-----------------------------------------------------------------------------*/

package fever.plugin.manager.abstract 
{
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import com.bourre.plugin.AbstractPlugin;
	
	import fever.error.AbstractConstructorAccessException;
	import fever.error.UnimplementedOverridingException;
	import fever.log.FeverDebug;
	import fever.plugin.FeverPlugin;
	import fever.plugin.manager.RegistredPlugin;
	import fever.plugin.manager.RegistredPluginInfo;
	import fever.plugin.manager.events.PluginActivationEvent;
	import fever.plugin.manager.events.PluginManagerEvent;
	import fever.plugin.manager.events.PluginRegistrationEvent;	

	/**
	 * Allow plugin to be registred into a <strong>Plugin manager</strong>.
	 * 
	 * @author Romain Ecarnot
	 */
	public class AbstractRegistredPlugin extends FeverPlugin 
		implements RegistredPlugin
	{
		//--------------------------------------------------------------------
		// Private properties
		//--------------------------------------------------------------------
		
		private var _bQuietMode : Boolean;
		private var _oTimer : Timer;
		
		
		//--------------------------------------------------------------------
		// Public properties
		//--------------------------------------------------------------------
		
		/**
		 * Delay millisecond to check manager connection.
		 * 
		 * @default 100
		 */
		public static var MANAGER_CHECK_INTERVAL : int = 100;
		
		/**
		 * Delay millisecond before detecting a manager timeout
		 * 
		 * @default 5000
		 */
		public static var MANAGER_TIMEOUT : int = 5000;
				
				
		//--------------------------------------------------------------------
		// Public API
		//--------------------------------------------------------------------
		
		/** 
		 * @inheritDoc
		 */
		public function onPluginRegistration( event : PluginRegistrationEvent ) : void
		{
			
		}
		
		/** 
		 * @inheritDoc
		 */
		public function onPluginActivation( event : PluginActivationEvent ) : void
		{
			if( event.activation )
			{
				try
				{
					_activatePlugin();	
				}	
				catch( eA : UnimplementedOverridingException )
				{
					FeverDebug.ERROR( eA.message );	
				}
			}
			else
			{
				try
				{
					_desactivatePlugin();	
				}	
				catch( eD : UnimplementedOverridingException )
				{
					FeverDebug.ERROR( eD.message );	
				}
			}
		}
		
		/** 
		 * @inheritDoc
		 */
		public function activate( ) : void
		{
			var event : PluginManagerEvent = new PluginManagerEvent(
				PluginManagerEvent.onActivatePluginEVENT,
				getChannel()
			);
			
			_fireManagerEvent( event );
		}
		
		/** 
		 * @inheritDoc
		 */
		public function desativate( ) : void
		{
			var event : PluginManagerEvent = new PluginManagerEvent(
				PluginManagerEvent.onDesactivatePluginEVENT, getChannel()
			);
			
			_fireManagerEvent( event );
		}
		
		
		//--------------------------------------------------------------------
		// Private implementations
		//--------------------------------------------------------------------
		
		/**
		 * Allows <strong>AbstractRegistredPlugin</strong> extension.<br />
		 * Pass <code>getConstructorAccess()</code> as 1st parameter when calling 
		 * super constructor.
		 * 
		 * @example
		 * <listing version=3.0>
		 * 
		 * package
		 * {
		 * 	class MyPlugin extends AbstractRegistredPlugin
		 * 	{
		 * 		public function MyPlugin( bypass : Boolean )
		 * 		{
		 * 			super( getContructorAccess(), bypass );
		 * 		}
		 * 	}
		 * } 
		 * </listing>
		 */
		protected final function getConstructorAccess() : AbstractAccess
		{
			return new AbstractAccess();	
		}
		
		/**
		 * @private
		 * Private constuctor, don't use it, extends it.
		 */
		public function AbstractRegistredPlugin( access : AbstractAccess, bypass : Boolean = false )
		{
			super();
			
			if( access == null )
			{
				throw new AbstractConstructorAccessException( this );
			}
			else
			{
				_bQuietMode = bypass;
				
				_registerToManager();
			}
		}	
		
		private function _registerToManager( ) : void
		{
			if( !_bQuietMode ) 
			{
				_oTimer = new Timer( MANAGER_CHECK_INTERVAL );
				_oTimer.addEventListener( TimerEvent.TIMER, _checkManagerHandler );
				_oTimer.start();
			}
		}
		
		private function _checkManagerHandler( event : TimerEvent ) : void
		{
			if( pluginManagerChannel != null )
			{
				_oTimer.stop( );
			}
			else
			{
				if( _oTimer.currentCount * MANAGER_CHECK_INTERVAL > MANAGER_TIMEOUT )
				{
					_oTimer.stop();
					
					_fireManagerEvent( new PluginManagerEvent( 
							PluginManagerEvent.onRegisterPluginEVENT, 
							getChannel(),
							_buildPluginData()
						)
					);
				}
			}
		}
		
		private function _fireManagerEvent( e : Event ) : void
		{
			fireExternalEvent(  e, pluginManagerChannel );	
		}
		
		protected function _buildPluginData( ) : RegistredPluginInfo
		{
			return new RegistredPluginInfo( this );
		}
		
		protected function _activatePlugin() : void
		{
			throw new UnimplementedOverridingException( "_activePlugin() mus be override" );
		}
		
		protected function _desactivatePlugin() : void
		{
			throw new UnimplementedOverridingException( "_activePlugin() mus be override" );
		}
	}
}

internal class AbstractAccess{}
